.global main

initStask:
    pushl %ebp
    movl %esp, %ebp
    subl $8, $esp
    subl $12, $esp
    pushl $40
    call malloc
    addl $16, %esp
    ; 把返回的void*指针放入edx
    movl %eax, %edx
    ; s->base
    movl 8(%ebp), %eax
    ; 把返回地址赋给s->base
    movl %edx, (%eax)

    ; 以下四行把s->base赋值给s->top
    movl 8(%ebp), %eax
    movl (%eax), %edx
    movl 8(ebp), %eax
    movl %edx, 4(%eax)

    ; 以下两行把10赋值给s->size
    movl 8(%ebp), %eax
    movl $10, 8(%eax)

    leave
    ret

push:
    pushl %ebp
    movl %esp, %ebp

    subl $8, %ebp
    ; s
    movl 8(%ebp), %eax
    movl 4(%eax), %edx
    movl 8(%eax), %eax
    movl (%eax), %ecx
    movl %edx, %eax
    subl %ecx, %eax
    ; 右移两位是为了得出int类型的长度，减后的值其实是字节，但int占4字节，故需要除以4，即右移两位
    sarl $2, %eax
    ; 把s->top - s->base的值暂存到edx
    movl %eax, %edx

    ; 获取s->size
    movl 8(%ebp), %eax
    movl 8(%eax), %eax
    ; 把s->top - s->base和s->size比较
    cmpl %eax, %edx
    jle .L4

    # 把s指针取出来放在eax中
    movl 8(%ebp), %eax
    movl (%eax), %eax
    sub $8, %esp
    # 调用realloc(s->base, 40)
    pushl $40
    pushl %eax
    call realloc
    addl $16, %esp

    # 把返回的eax放到s->base中
    movl 8(%ebp), %edx
    movl %eax, (%edx)

    movl 8(%ebp), %eax
    movl (%eax), %eax
    testl %eax, %eax
    jne .L5
    movl $0, %eax
    jmp .L6
.L5:
    movl 8(%ebp), %eax
    movl 8(%eax), %eax
    leal 10(%eax), %edx
    movl 8(%ebp), %eax
    movl %edx, 8(%eax)
.L4:
    # 取得s->top
    movl 8(%ebp), %eax
    movl 4(%eax), %eax
    # e
    movl 12(%ebp), %edx
    # 把e放到s->top中
    movl %edx, (%eax)
    # 取得s指针
    movl 8(%ebp), %eax
    # 将s->top放到eax
    movl 4(%eax), %eax
    leal 4(%eax), %edx
    movl 8(%esp), %eax
    movl %edx, 4(%eax)
    movl $1, %eax
.L6:
    leave
    ret

pop:
    pushl %ebp
    movl %esp, %ebp

    movl 8(%ebp), %eax
    movl (%eax), %edx
    movl 8(%ebp), %eax
    movl 4(%eax), %eax
    cmpl %eax, %edx
    jne .L8
    movl $0, %eax
    jmp .L9

.L8:
    movl 8(%ebp), %eax
    # 将s->top放入eax
    movl 4(%eax), %eax
    leal -4(%eax), %edx
    movl 8(%ebp), %eax
    movl %edx, 4(%eax)

    movl 8(%ebp), %eax
    movl 4(%eax), %eax
    movl (%eax), %edx
    movl 12(%ebp), %eax
    movl %edx, (%eax)
    movl $1, %eax
.L9:

    popl %ebp
    ret

stack_size:
    pushl %ebp
    movl %esp, %ebp

    movl 8(%ebp), %eax
    movl 4(%eax), %edx
    movl 8(%ebp), %eax
    movl (%eax), %ecx
    movl %edx, %eax
    subl %ecx, %eax
    sarl $2, %eax
    leave
    ret

delete_return:
    pushl %ebp
    movl %esp, %ebp

    subl $24, %esp
    subl $12, %esp
    # 将s指针push到栈中，准备调用strlen函数
    pushl 8(%ebp)
    call strlen
    add $16, %esp

    # 将返回值，即字符串长度放入临时变量size
    movl %eax, -12(%ebp)
    movl -12(%ebp), %eax
    leal -1(%ebp), %edx
    movl 8(%ebp), %eax
    addl %edx, %eax
    movzbl (%eax), %eax
    cmpb $10, %al
    jne .L14

    movl -12(%ebp), %eax
    leal -1(%eax), %edx
    movl 8(%ebp), %eax
    addl %edx, %eax
    movl $0, (%eax)

.L14:
    nop
    leave
    ret

is_empty:
    pushl %ebp
    movl %esp, %ebp

    movl 8(%ebp), %eax
    movl (%eax), %eax
    pushl %eax
    call strlen

    cmp 0, %eax
    je $.L15
    movl $0, %eax
    jmp $.L16
.L15:
    movl $1, %eax
.L16:
    leave
    ret

# 以上是我自己写的is_empty
# 下面是compiler explorer生成的，好像意思一样
# 但效率应该比较高，因为少了调用strlen函数
is_empty1:
    pushl %ebp
    movl %esp, %ebp

    movl 8(%ebp), %eax
    movzbl (%eax), %eax
    testb %al, %al
    sete %al
    movzbl %al, %eax
    popl %ebp
    ret

.LC0:
        .string "input number or operator\357\274\232"
.LC1:
        .string "input error, operator is add, but no operand"
.LC2:
        .string "input error, operator is add, but only one operand"
.LC3:
        .string "input error, operator is sub, but no operand"
.LC4:
        .string "input error, operator is sub, but only one operand"
.LC5:
        .string "input error, operator is mul, but no operand"
.LC6:
        .string "input error, operator is mul, but only one operand"
.LC7:
        .string "input error, operator is div, but no operand"
.LC8:
        .string "input error, operator is div, but only one operand"
.LC9:
        .string "input error, after calculate, the result count is not 1"
.LC10:
        .string "the result is %d\n"

main:
    leal 4(%esp), %ecx
    andl $-16, %esp
    pushl -4(%ecx)

    # 上面的不懂什么意思

    pushl %ebp
    movl %esp, %ebp

    # 以下这个语句也不知道什么意思
    pushl %ecx
    subl $84, %esp
    subl $12, $esp

    leal -40(%ebp), %eax
    pushl %eax
    call initStask

    addl $16, %esp

.L35:
    subl $12, $esp
    pushl $.LC0
    call puts
    addl $16, %esp

    movl stdin, %eax
    subl $4, %esp
    pushl %eax
    pushl $11
    # cs
    leal -51(%ebp), %eax
    pushl %eax
    call fgets
    addl $16, %esp

    subl $12, %esp
    leal -51(%ebp), %eax
    push %eax
    call delete_return
    addl $16, %esp

    subl $12, %esp
    leal -51(%ebp), %eax
    pushl %eax
    call is_empty
    addl $16, %esp

    testl %eax, %eax
    setne %al
    testb %al, %al
    jne .L39

    subl $12, %esp
    leal -51(%ebp), %eax
    pushl %eax
    call strlen
    addl $16, %esp
    cmpl $1, %eax
    jne .LC21

    # 获取cs[0]
    movzbl -51(%ebp), %eax
    movsbl %al, %eax
    # 判断是否是除号/
    cmpl $47, %eax
    # 如果是跳到.L22
    je .L22
    cmpl $47, %eax
    # 大于47跳转到.L40
    jg .L40

    # 判断是否是减号
    cmpl $45, %eax
    je .L24
    cmpl $45, %eax
    jg .L40

    # 判断是否乘号
    cmpl $42, %eax
    je .L25
    cmpl $43, %eax
    jne .L40

    subl $8, %esp
    # b
    leal -64(%ebp), %eax
    pushl %eax
    # &s
    leal -40(%ebp), %eax
    pushl %eax
    call pop
    addl $16, %esp

    cmpl $1, %eax
    setne %al
    testb %al, %al
    je .L26

    subl $12, %esp
    pushl $.LC1
    call puts
    addl $16, %esp
    subl $12, %esp
    pushl $1
    call exit
.L26:
    subl $8, %esp
    # a
    leal -60(%ebp), %eax
    pushl %eax
    leal -40(%ebp), %eax
    pushl %eax
    call pop
    addl $16, %esp
    cmpl $1, %eax
    setne %al
    testb %al, %addl
    je .L27
    subl $12, %esp
    pushl $.LC2
    call puts
    addl $16, %esp

    subl $12, %esp
    pushl $1
    call exit

.L27:
    movl -60(%ebp), %eax
    movl -64(%ebp), %edx
    addl %edx, %eax
    # result
    movl %eax, -20(ebp)
    subl $8, %esp
    pushl -20(%ebp)
    
    leave
    ret